﻿using System;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;

namespace ZSW.Framework.Utils
{
    public static class ZSWFUtil_String
    {
        /// <summary>
        /// 字符串数组拼接成字符串
        /// </summary>
        /// <param name="arr"></param>
        /// <param name="separator"></param>
        /// <returns></returns>
        public static string Join(string[] arr, string separator = "")
        {
            if (arr == null || arr.Length == 0)
                return "";

            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < arr.Length - 1; i++)
            {
                sb.Append(arr[i]);
                sb.Append(separator);
            }

            sb.Append(arr[arr.Length - 1]);

            return sb.ToString();
        }

        /// <summary>
        /// 计算比较两个字符串的相似度
        /// </summary>
        /// <param name="str1"></param>
        /// <param name="str2"></param>
        /// <returns></returns>
        public static float Compare(string str1, string str2)
        {
            char[] charArray1 = str1.ToCharArray();
            char[] charArray2 = str2.ToCharArray();

            int l1 = charArray1.Length;
            int l2 = charArray2.Length;

            int maxLen = Math.Max(l1, l2);
            if (maxLen == 0) return 1.0f;

            float distance = levenshteinDistance(charArray1, charArray2);
            // distance *= 1.5f;  // 权重
            float similarity = 1 - (float)distance / maxLen;

            return similarity;
        }

        /// <summary>
        /// 计算从一个字符串转换成另一个字符串,需要的最少编辑操作次数
        /// </summary>
        /// <param name="s"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        private static int levenshteinDistance(char[] s, char[] t)
        {
            var n = s.Length;
            var m = t.Length;
            var d = new int[n + 1, m + 1];

            if (n == 0) return m;
            if (m == 0) return n;

            for (int i = 0; i <= n; d[i, 0] = i++) ;
            for (int j = 0; j <= m; d[0, j] = j++) ;

            for (int i = 1; i <= n; i++)
            {
                for (int j = 1; j <= m; j++)
                {
                    var cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
                    d[i, j] = Mathf.Min(
                            Mathf.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
                            d[i - 1, j - 1] + cost
                    );
                }
            }

            return d[n, m];
        }

        /// <summary>
        /// 获取字符串中关键字括号内的内容
        /// 比如 [Test(abc)] => abc
        /// </summary>
        /// <param name="input"></param>
        /// <param name="keyword"></param>
        /// <returns></returns>
        public static string ExtractString(string input, string keyword)
        {
            int startIndex = input.IndexOf("[" + keyword);
            if (startIndex == -1) return "";

            startIndex += keyword.Length + 1;

            int endIndex = input.IndexOf(")", startIndex);
            if (endIndex == -1) return "";

            startIndex += 1; // 去掉左括号
            // endIndex += 1; // 包含右括号

            return input.Substring(startIndex, endIndex - startIndex);
        }

        public static string GetKeyFromJsonStr(string jsonStr, string key)
        {
            string json_str_remove_space = RemoveAllSpace(jsonStr);
            string pattern = $"\"{key}\":\"([^\"]+)\"";
            Match match = Regex.Match(json_str_remove_space, pattern);
            return match.Success ? match.Groups[1].Value : "";
        }

        /// <summary>
        /// 移除字符串中的所有空格
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string RemoveAllSpace(string str)
        {
            return Regex.Replace(str, @"\s", "");
        }

        /// <summary>
        /// 是否为null或者""
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static bool IsEmpty(this string s) => string.IsNullOrEmpty(s);
        public static string Blue(this string s, bool bold = false) => bold ? Color(Bold(s), 0x0000FF) : Color(s, 0x0000FF);
        public static string Sky(this string s, bool bold = false) => bold ? Color(Bold(s), 0x00FFFF) : Color(s, 0x00FFFF);
        public static string Teal(this string s, bool bold = false) => bold ? Color(Bold(s), 0x008080) : Color(s, 0x008080);
        public static string Green(this string s, bool bold = false) => bold ? Color(Bold(s), 0x00FF00) : Color(s, 0x00FF00);
        public static string Yellow(this string s, bool bold = false) => bold ? Color(Bold(s), 0xFFFF10) : Color(s, 0xFFFF00);
        public static string Gold(this string s, bool bold = false) => bold ? Color(Bold(s), 0xFFD700) : Color(s, 0xFFD700);
        public static string Orange(this string s, bool bold = false) => bold ? Color(Bold(s), 0xFFAA00) : Color(s, 0xFFAA00);
        public static string Red(this string s, bool bold = false) => bold ? Color(Bold(s), 0xFF0000) : Color(s, 0xFF0000);
        public static string Magenta(this string s, bool bold = false) => bold ? Color(Bold(s), 0xFF00FF) : Color(s, 0xFF00FF);
        public static string Purple(this string s, bool bold = false) => bold ? Color(Bold(s), 0x800080) : Color(s, 0x800080);
        public static string Gray(this string s, bool bold = false) => bold ? Color(Bold(s), 0xAAAAAA) : Color(s, 0xAAAAAA);
        public static string Silver(this string s, bool bold = false) => bold ? Color(Bold(s), 0xC0C0C0) : Color(s, 0xC0C0C0);

        public static string xC5C8A9(this string s, bool bold = false) => bold ? Color(Bold(s), 0xC5C8A9) : Color(s, 0xC5C8A9);
        public static string x96A48A(this string s, bool bold = false) => bold ? Color(Bold(s), 0x96A48A) : Color(s, 0x96A48A);
        public static string xA5BCCE(this string s, bool bold = false) => bold ? Color(Bold(s), 0xA5BCCE) : Color(s, 0xA5BCCE);

        public static string xE1D0B8(this string s, bool bold = false) => bold ? Color(Bold(s), 0xE1D0B8) : Color(s, 0xE1D0B8);
        public static string xE5BD73(this string s, bool bold = false) => bold ? Color(Bold(s), 0xE5BD73) : Color(s, 0xE5BD73);
        public static string xBC9575(this string s, bool bold = false) => bold ? Color(Bold(s), 0xBC9575) : Color(s, 0xBC9575);

        public static string xD9919E(this string s, bool bold = false) => bold ? Color(Bold(s), 0xD9919E) : Color(s, 0xD9919E);
        public static string xE38C7A(this string s, bool bold = false) => bold ? Color(Bold(s), 0xE38C7A) : Color(s, 0xE38C7A);
        public static string x96504B(this string s, bool bold = false) => bold ? Color(Bold(s), 0x96504B) : Color(s, 0x96504B);

        public static string Bold(this string s) => $"<b>{s}</b>";

        /// <summary>
        /// 设置富文本颜色 (自定义)
        /// </summary>
        /// <param name="s"></param>
        /// <param name="color"></param>
        /// <returns></returns>
        public static string Color(string s, int color) => $"<color=#{color:X6}>{s}</color>";

        public static bool ToBool(string str)
        {
            bool.TryParse(str, out bool res);
            if (str.ToUpper() == "TRUE" || res) return true;
            return false;
        }

        public static float ToFloat(string str, float defaultValue = -1)
        {
            if (float.TryParse(str, out float res))
            {
                return res;
            }

            return defaultValue;
        }

        public static int ToInt(string str, int defaultValue = -1)
        {
            if (int.TryParse(str, out int res))
            {
                return res;
            }

            return defaultValue;
        }

        public static long ToLong(string str, long defaultValue = -1)
        {
            if (long.TryParse(str, out long res))
            {
                return res;
            }

            return defaultValue;
        }

        public static double ToDouble(string str, double defaultValue = -1)
        {
            if (double.TryParse(str, out double res))
            {
                return res;
            }

            return defaultValue;
        }
    }
}